import axios from 'axios';
import pinia from './pinia';
import { useUserStore } from '../store/user';

const user = useUserStore(pinia);

// api
const apiHost = ''; // 接口地址

let http = axios.create({
  // 当前环境为线上时，自动使用production环境变量里的VITE_API_BASEURL线上接口地址
  baseURL: import.meta.env.MODE === 'production' ? import.meta.env.VITE_API_BASEURL : apiHost,
  timeout: 60000
});

// 参数配置
let needLoading = true, // 是否需要loading
  needErrorNotify = true, // 是否需要错误提示
  requestCount = 0; // 请求数量，用于loading控制，避免多个接口并发时重复loading

// loading操作
const ShowLoading = () => {
  if (requestCount === 0) {
    $uiMsg.loading('加载中');
  }
  requestCount++;
};
const HideLoading = () => {
  requestCount--;
  if (requestCount <= 0) {
    requestCount = 0;
    $uiMsg.removeMessage();
  }
};

http.interceptors.request.use(config => {
  // 切换组件时，取消还未完成的请求
  config.cancelToken = new axios.CancelToken(cancel => {
    window.__axiosPromiseArr.push({
      url: config.url,
      cancel
    });
  });
  if (needLoading) {
    ShowLoading();
  }
  if (user.token) {
    config.headers.Authorization = 'Bearer ' + user.token;
  }
  config.headers.post['Content-Type'] = 'application/json;charset=UTF-8;';
  return config;
});
http.interceptors.response.use(
  response => {
    if (needLoading) {
      HideLoading();
    }
    // 换token时报错，退出登录
    if (response.config.url.indexOf('/token') !== -1 && response.data.code !== 200) {
      $uiMsg.error('登录已过期，请重新登录', () => {
        user.LoginOut();
      });
      return;
    }
    return response.data;
  },
  error => {
    HideLoading();
    if (error.response && error.response.status === 401) {
      // token过期访问刷新token的接口
      return http
        .post('/token', JSON.stringify(user.token))
        .then(res => {
          if (res.code !== 200) {
            $uiMsg.error(res.msg);
            return;
          }
          // 更新pinia里的数据
          user.LoginIn(res.body);
          // 刷新token后重新请求之前的接口
          const config = error.response.config;
          config.headers.Authorization = 'Bearer ' + res.body.token;
          return http(config);
        })
        .catch(error => {
          $uiMsg.error(error.msg);
        });
    } else {
      $uiMsg.error('网络错误，请稍后再试');
      return Promise.reject(error);
    }
  }
);

const get = (url, params, _needLoading = true, _needErrorNotify = true) => {
  needLoading = _needLoading;
  needErrorNotify = _needErrorNotify;
  return new Promise((resolve, reject) => {
    let _timestamp = new Date().getTime();
    http
      .get(url, { params })
      .then(res => {
        if (new Date().getTime() - _timestamp < 200) {
          setTimeout(() => {
            if (res?.code === 200) {
              resolve(res);
            } else {
              needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
              reject(res);
            }
          }, 200);
        } else {
          if (res?.code === 200) {
            resolve(res);
          } else {
            needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
            reject(res);
          }
        }
      })
      .catch(error => {
        reject(error);
      });
  });
};

const post = (url, params, _needLoading = true, _needErrorNotify = true) => {
  needLoading = _needLoading;
  needErrorNotify = _needErrorNotify;
  return new Promise((resolve, reject) => {
    let _timestamp = new Date().getTime();
    http
      .post(url, params)
      .then(res => {
        if (new Date().getTime() - _timestamp < 200) {
          setTimeout(() => {
            if (res?.code === 200) {
              resolve(res);
            } else {
              needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
              reject(res);
            }
          }, 200);
        } else {
          if (res?.code === 200) {
            resolve(res);
          } else {
            needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
            reject(res);
          }
        }
      })
      .catch(error => {
        reject(error);
      });
  });
};

export { get, post };
